/*                                  ATELIER                                   */

/* %%LICENSE_TAG%%                                                            */
package edu.gmu.view.canvas.graph;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JPanel;

import javax.swing.Action;
import edu.gmu.view.canvas.Canvas;
import edu.gmu.view.canvas.CursorLayer;
import javax.swing.AbstractAction;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingUtilities;


/**
 * The GraphPanel displays currently collected motes.
 *
 * @author  James H. Pope
 * @version $Revision:$ $Date:$
 */
public class GraphPanel extends JPanel
{
    /****************************  GUI components  ****************************/
    protected Canvas canvas = null;
    
    /**
     *
     */
    protected GraphLayer graphLayer = null;
    
    /**
     *
     */
    protected GraphCursorLayer cursorLayer = null;

    /**
     *
     */
    protected JButton zoomInButton  = null;
    /**
     *
     */
    protected JButton zoomOutButton = null;

    /**
     *
     */
    protected JButton compressButton = null;
    /**
     *
     */
    protected JButton expandButton   = null;
    
    /**
     * Creates a new instance of GraphPanel
     */
    public GraphPanel( )
    {   
    	// Set Layout
    	Dimension dim = new Dimension( 400, 125 );
    	this.setPreferredSize( dim );
    	//this.setMaximumSize( dim );
        this.setMinimumSize( dim );
        //this.setSize( dim );
    	
    	BorderLayout mainLayout = new BorderLayout();
        this.setLayout( mainLayout );
        
        int frameRate = 20;
        this.canvas = new Canvas( frameRate );
        //this.canvas.setPreferredSize( dim );
        
        this.graphLayer = new GraphLayer( );
        this.cursorLayer = new GraphCursorLayer( CursorLayer.VERTICAL, Color.WHITE );
        this.cursorLayer.setReadoutAdapter(graphLayer);

        this.canvas.getLayerModel().addLayer( cursorLayer );
        this.canvas.getLayerModel().addLayer( graphLayer );
        
        
        Action zoomInAction = new AbstractAction( "+" )
        {
        	public void actionPerformed(ActionEvent event)
        	{
        		double currentScale = graphLayer.getVerticalScale();
        		graphLayer.setVerticalScale( currentScale / 2.0 );
        	}
        };
        
        Action zoomOutAction = new AbstractAction( "-" )
        {
        	public void actionPerformed(ActionEvent event)
        	{
        		double currentScale = graphLayer.getVerticalScale();
        		graphLayer.setVerticalScale( currentScale * 2.0 );
        	}
        };


        Action compressAction = new AbstractAction( "<" )
        {
        	public void actionPerformed(ActionEvent event)
        	{
        		double currentScale = graphLayer.getHorizontalScale();
        		graphLayer.setHorizontalScale( currentScale / 2.0 );
        	}
        };

        Action expandAction = new AbstractAction( ">" )
        {
        	public void actionPerformed(ActionEvent event)
        	{
        		double currentScale = graphLayer.getHorizontalScale();
        		graphLayer.setHorizontalScale( currentScale * 2.0 );
        	}
        };

        
        
        this.zoomInButton  = new JButton( zoomInAction );
        this.zoomOutButton = new JButton( zoomOutAction );

        this.compressButton = new JButton( compressAction );
        this.expandButton   = new JButton( expandAction );

        /*
         * Canvas can be used in a ScrollPane only if the layer(s)
         * properly update the preferredSize of the canvas component.
         */
        JScrollPane scrollPane = new JScrollPane( );
        scrollPane.setViewportView( this.canvas );
        scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);

        Dimension buttonDim = new Dimension( 30, 22 );
        
        zoomInButton.setPreferredSize(buttonDim);
        zoomInButton.setMaximumSize(buttonDim);
        zoomInButton.setMinimumSize(buttonDim);

        zoomOutButton.setPreferredSize(buttonDim);
        zoomOutButton.setMaximumSize(buttonDim);
        zoomOutButton.setMinimumSize(buttonDim);

        compressButton.setPreferredSize(buttonDim);
        compressButton.setMaximumSize(buttonDim);
        compressButton.setMinimumSize(buttonDim);

        expandButton.setPreferredSize(buttonDim);
        expandButton.setMaximumSize(buttonDim);
        expandButton.setMinimumSize(buttonDim);



        
        JPanel controlPanel = new JPanel();
        BoxLayout controlLayout = new BoxLayout( controlPanel, BoxLayout.Y_AXIS );
        controlPanel.setLayout( controlLayout );
        
        controlPanel.add( zoomInButton );
        controlPanel.add( zoomOutButton );
        controlPanel.add( compressButton );
        controlPanel.add( expandButton );

        this.add( controlPanel,  BorderLayout.WEST );
        this.add( scrollPane, BorderLayout.CENTER );
        
        
        this.canvas.start();
    }

    /**
     * Sets applicable components enabled.
     *
     * @param enabled
     */
    public void setGraphEnabled( final boolean enabled )
    {
        //------------------------------------------------------------//
        // Unknown thread
        //------------------------------------------------------------//
        /*
         * We do not know if this will be called from a non-EDT Thread
         * But we do know that the following code has to be run on the
         * EDT - therefore - make sure that it is!!!
         */
        Runnable task = new Runnable()
        {
            public void run()
            {
                //------------------------------------------------------------//
                // EDT
                //------------------------------------------------------------//
                canvas.setEnabled(enabled);
                //this.horizontalScrollbar.setEnabled(enabled);

                /*
                 * Need to ensure done on EDT!!!!
                 */
                zoomInButton.setEnabled(enabled);
                zoomOutButton.setEnabled(enabled);

                compressButton.setEnabled(enabled);
                expandButton.setEnabled(enabled);
                //------------------------------------------------------------//
            }
        };

        SwingUtilities.invokeLater(task);
        //------------------------------------------------------------//
    }
    
    /**
     * Convenient access to GraphLayer.
     * 
     * @return GraphLayer graphLayer
     */
    public GraphLayer getGraphLayer()
    {
    	return this.graphLayer;
    }
}

/*                                  ATELIER                                   */